if 0
img_txt_bin:
       .ptr       equ      [ebp-4]
       .file_size equ dword[ebp-8]
       .data_size equ dword[ebp-12]
       .string    equ [ebp-70]
       push      ebp
       mov       ebp,esp
       sub       esp,90
      
       malloc    90000
       mov       .ptr,eax
       mov       edi,eax
       mov       esi,img_txt
       mov       ecx,img_txt_size
       int3
       cld
     .ll2:  
       push      edi
       lea       edi,.string
     .ll:
       lodsb
       stosb
       cmp       al,' '
       je        .conv
       loop      .ll
       jmp       .en1
     .conv:
       mov       ebx,edi
       sub       ebx,2
       push      ecx esi
       call      ascii_to_integer
       pop       esi ecx
       mov       eax,edx
       pop       edi
       stosb
       loop      .ll2
       jmp       .en
     .en1:
       pop       edi
     .en:
       int3
       sub       edi,   .ptr
       mov       edx,   .ptr
       movups    xmm0,[edx]
       mov       eax,   bin_img_file_name
       mov       ecx,   edi ;   img_txt_size
       call      save_fileA
       mfree     .ptr      
       mov       esp,ebp
       pop       ebp
ret
end if
if 0
save_bezier_rects:
; convert sequences 16 bit words  
; into 9 bit 
       .ptr       equ      [ebp-4]
       .file_size equ dword[ebp-8]
       .data_size equ dword[ebp-12]
       
       push     ebp
       mov      ebp,esp
       sub      esp,28
      
       malloc    30000
       mov       .ptr,eax
       mov       edi,eax
       xor       eax,eax
       mov       ecx,6000
       cl
       rep       stosd
       mov       esi,  tspoon_rect
       mov       ecx,(32+26+16+6)*2
       ; 256 words into 256+(256/8) bytes 
       mov       eax,((32+26+16+6)*18)  ;+((32+26+16+6)) + 1  
       mov       .file_size, eax
       mov       edi,  .ptr
     .ll:
       movups    xmm1,[esi]
       ; i will pack to 9 bits per single value
       push      ecx
       xor       ecx,ecx
      @@: 
       movd      eax,xmm1
       and       eax,0x1ff
       psrldq    xmm1,2 
       shl       eax,cl
       or        [edi],eax
       inc       edi
       inc       cl
       cmp       cl,8
       jnz       @b
       pop       ecx
       inc       edi       
       add       esi,16 ; 8 words at once
       loop      .ll
       
       xor       eax,eax
       mov       [edi],eax
       
       mov      edx,   .ptr
       mov      eax,   bez_file_name
       mov      ecx,   .file_size
       call     save_fileA
       mfree    .ptr      
       mov      esp,ebp
       pop      ebp
ret
end if
;===============================
if 0
save_bezier:
; convert sequences of 32 bit floats 
; into 11 bit unsigned int
; esi = source of bunch dwords
; edi = destination
       .ptr       equ      [ebp-4]
       .file_size equ dword[ebp-8]
       .data_size equ dword[ebp-12]
       
       push     ebp
       mov      ebp,esp
       sub      esp,28
      
       malloc    30000
       mov       .ptr,eax
       mov       edi,eax
       xor       eax,eax
       mov       ecx,4000
       cld
       rep       stosd
       mov       eax,  1000
       cvtsi2ss  xmm2, eax
       shufps    xmm2, xmm2,0
       mov       eax,  1010
       cvtsi2ss  xmm3, eax
       shufps    xmm3, xmm3,0
       mov       esi,  tspoon_nodes
       mov       ecx,  ((256 + 251 + 306 + 56)*3/8) + 1 
       mov       eax,  0xe10 
       mov       .file_size, eax 
       mov        edi,  .ptr
     .ll:
       movups    xmm0, [esi]
       mulps     xmm0, xmm2
       addps     xmm0, xmm3
       movups    xmm4, [esi+16]
       mulps     xmm4, xmm2
       addps     xmm4, xmm3
       cvtps2dq  xmm4, xmm4
       packusdw  xmm4, xmm4
             
       cvtps2dq  xmm1, xmm0
       packusdw  xmm1, xmm1
       movlhps   xmm1, xmm4
       ; i will pack to 11 bits per single value
       push      ecx
       xor       ecx,ecx
      @@: 
       movd      eax,xmm1
       and       eax,0x7ff
       psrldq    xmm1,2 
       shl       eax,cl
       or        [edi],eax
       inc       edi
       add       ecx,3
       cmp       ecx,24
       jnz       @b
       pop       ecx
       add       edi,3     
       add       esi,32
       loop      .ll
       
       xor      eax,eax
       mov       [edi],eax

       mov      edx,   .ptr
       mov      eax,   bez_file_name
       mov      ecx,   .file_size
       call     save_fileA
       mfree    .ptr      
       mov      esp,ebp
       pop      ebp
ret
end if
;======================================================
save_wav:
; in:
;  eax = amplitude factor
;  if ebx != 0 then ebx = ptr address to write sample and
;  no mem is allocated
;  I assume 8 bit and ptr non zero as *.mod file
       .ptr   equ  [ebp-4]
       .fact  equ  word[ebp-6]
       .note  equ  word[ebp-8]
       .fact2 equ  word[ebp-12]
       .note2 equ  [ebp-16]
       .xres  equ  [ebp-20]
       .yres  equ  [ebp-24]
       .bits  equ  [ebp-28]

       .file_size equ dword[edi+4]
       .data_size equ dword[edi+40]
       
       push     ebp
       mov      ebp,esp
       sub      esp,28
       mov      .bits,eax
       mov      .ptr,ebx
       mov      edi,ebx
       mov      ax,90
       mov      .note,ax
       mov      .fact,ax
       mov      ax,255
       mov      .fact2,ax
       
       mov      eax,xres_var
       movzx    edx,word[eax]
       movzx    esi,word[eax+2]
       mov      .xres,edx
       mov      .yres,esi
       or       ebx,ebx
       jnz      .raw_ptr

       mov      eax,14000000
       malloc   eax
       mov      edi,eax
       mov      .ptr,eax


       mov      eax,'RIFF'
       cld
       stosd
       ; file size
       stosd
       mov      eax,'WAVE'
       stosd
       mov      eax,'fmt '
       stosd
       mov      eax,16
       stosd
       mov      ax,1
       stosw
       mov      ax,1        ; chanels count
       stosw
       mov      eax,44100   ; sampling frequency
       stosd
       mov      eax,0xac44
       stosd
       mov      ax,2        ; bytes per sample
       stosw
       mov      ax,16       ; bits per sample
       stosw
       mov      eax,'data'  ; begin of data
       stosd
       ; data size
       stosd
       
     .raw_ptr:
       mov      edx,.yres
       cvtsi2ss xmm1,edx
       rcpps    xmm1,xmm1
       mov      eax,1
       mov      cl,.bits
       dec      cl
       shl      eax,cl
       dec      eax
       cvtsi2ss xmm2,eax
       movzx    eax,[tolerancy_flag]
       inc      eax
       mov      edx,0.15
       cvtsi2ss xmm7,eax
       movd     xmm6,edx
       mulps    xmm7,xmm6      ; xm7 - delta
       
       mov      ecx,20
       xor      edx,edx
       xorps    xmm6,xmm6
       mov      eax,0.5
       movd     xmm5,eax
       shufps   xmm5,xmm5,0
     .l0:                      ; xm6 - curr
       push     ecx
       mov      esi,[screen_ptr]
       mov      ebx,.xres
       mov      ecx,ebx
       shl      ebx,2
     .l1:
       push     esi
       push     ecx
       mov      ecx,.yres
     .l2:
       mov      eax,[esi+ebx]
       or       eax,eax
       jz       .ff
       cvtsi2ss xmm0,ecx
       mulps    xmm0,xmm1
    ;   subps    xmm0,[the_one]
       subps     xmm0,xmm5
       mulps    xmm0,xmm2
       addps    xmm6,xmm7
       cvtss2si eax,xmm6
       sub      eax,edx
       push     ecx
       mov      ecx,eax
       cvtss2si eax,xmm0
       or       ecx,ecx
       jbe      .fa

       add      edx,ecx
       cmp      .bits,byte 8
       je       @f
       rep      stosw
       jmp      .fa
     @@:
       rep      stosb
     .fa:
       pop      ecx
       jmp      .en1
     .ff:
       add      esi,ebx
       loop    .l2
     .en1:
       pop      ecx
       pop      esi
       add      esi,4
       loop     .l1
       pop      ecx
       loop     .l0
       
       mov      ecx,4
     .lll:
       push     ecx
       mov      ecx,edx
       mov      esi,.ptr
       rep      movsd
       pop      ecx
       loop     .lll

       cmp      byte .bits,8
       je       .end     ; mod file

       mov      eax,edi
       sub      eax,.ptr
       mov      edi,.ptr
       mov      .file_size,eax
       sub      eax,40
       mov      .data_size,eax
       
       
       
     if 0
       
       mov      ecx,edx
       add      edx,edx
       mov      esi,edi
       sub      esi,edx
       fninit
       rcpps    xmm3,xmm2
     .lll:
       lodsd
       cvtsi2ss xmm0,eax
       movaps   xmm7,xmm0
       mulps    xmm0,xmm3
       movss   .note2,xmm0
       fld      dword .note2
       fldpi
       fldpi
       faddp
       fmulp
       fsin
       fstp     dword .note2
       mulss    xmm7,.note2
       cvtss2si eax,xmm7
       stosw
       loop    .lll
     end if
     if 0
       xor      eax,eax
       shr      ecx,1
       xor      bx,bx
     @@:
       fninit
       inc      al
       add      bx,1
       mov      .note,ax
       fild     .note
       ;   fmul     st,st0
       ;   fmul     st,st0
       fidiv    .fact
       fsin
       mov      .fact2,bx
       fimul    .fact2
       fistp    .note
       mov      ax,.note
       ;   mov      ah,al
       stosw
       loop     @b
     end if
       
       mov      edx,.ptr
       mov      eax,wav_file_name
       mov      ecx,.file_size
       call     save_fileA
       mfree    .ptr
     .end:

       mov      esp,ebp
       pop      ebp
ret
;===================================
save_mod:
       .ptr   equ  [ebp-4]
       .fact  equ  word[ebp-6]
       .note  equ  word[ebp-8]
       .fact2 equ  word[ebp-12]
       .fact4 equ  word[ebp-14]
       
       push       ebp
       mov        ebp,esp
       mov        eax,4000000
       malloc     eax
       mov        edi,eax
       push       eax
       
       mov        ax,600     ; various factors
       push       ax
       push       ax
       mov        ax,255
       push       ax
       mov        ax,1000
       push       ax
       
       mov        eax,'song'
       cld
       stosd
       xor        al,al
       mov        ecx,16
       rep        stosb
       mov        ecx,3    ; 3 samples
     @@:
       push       ecx
       mov        eax,'samp'                               ; \
       stosd                                               ; |
       mov        eax,'le n'                               ; |
       stosd                                               ; |
       mov        eax,'ame '                               ; |
       stosd                                               ; | 30 bytes
       mov        al,' '                                   ; | one sample info
       mov        ecx,12                                   ; |
       rep        stosb                                    ; |
       mov        ax,2000  ; sample lenght (in words)      ; |
       stosw                                               ; |
       mov        al,0b    ; fine tunevalue                ; |
       stosb                                               ; |
       mov        al,63    ; volume, range 0-64 decimal    ; |
       stosb                                               ; |
       mov        ax,0x01  ; repeat point                  ; |
       stosw                                               ; |
       mov        ax,0x0   ; repeat lenght                 ;/
       pop        ecx
       loop       @b
       
       mov        edi,.ptr
       add        edi,950
       mov        al,4     ; song lenght = 4 patterns
       stosb
       mov        al,127   ; always '127'
       stosb
       mov        ecx,8
     @@:
       mov        al,0     ; song positions , only one '0' pattern
       stosb
       inc        al
       loop       @b
       mov        al,0
       mov        ecx,120
       rep        stosb
       mov        edi,.ptr
       add        edi,1080
       mov        eax,'M.K.'
       stosd
       ; now patterns
       ;     Info for each note:
       ;
       ;  _____byte 1_____   byte2_    _____byte 3_____   byte4_
       ; /                \ /      \  /                \ /      \
       ; 0000          0000-00000000  0000          0000-00000000
       ;
       ; Upper four    12 bits for    Lower four    Effect command.
       ; bits of sam-  note period.   bits of sam-
       ; ple number.                  ple number.
       ; Periodtable for Tuning 0, Normal
       ; C-1 to B-1 : 856,808,762,720,678,640,604,570,538,508,480,453
       ; C-2 to B-2 : 428,404,381,360,339,320,302,285,269,254,240,226
       ; C-3 to B-3 : 214,202,190,180,170,160,151,143,135,127,120,113
       ; 856,808,762,720,678,640,604,570,538,508,480,453 = usual row
       mov        ecx,32   ; two paterns
       mov        edx,113
     @@:
       push       ecx
       and        edx,0x00000fff
       mov        eax,edx
       shl        eax,16
;       mov        eax,0x008f1c20
       mov        ax,0x1c20
       bswap      eax ; spppseee
       stosd      ; 1 rows
   ;    mov        eax,0x008f1481  ; e = vibrato
   ;    bswap      eax ; spppseee
       stosd      ; 1 rows
       mov        ecx,2
       rep        stosd
   ;    mov        eax,0x02801e01   ; s = smaple number
   ;    bswap      eax ; spppseee   ; p = period
       stosd                        ; e = effect
       stosd
       mov        ecx,15
       xor        eax,eax
       rep        stosd
    ;   mov        eax,0x03201100
    ;   bswap      eax ; spppseee   ;
       stosd
       mov        ecx,3  ; 64 bytes
       xor        eax,eax
       rep        stosd
       add        edx,14
       pop        ecx
       loop       @b
; protracker.txt file
; Mark J Cox -------------------- m.j.h.cox@bradford.ac.uk
; University of Bradford ----- bc732@cleveland.freenet.edu
; Mark
;             EFFECT COMMANDS
;             ---------------
; Effect commands on protracker should
; be compatible with all other trackers.
; 0 - None/Arpeggio     8 - * NOT USED *
; 1 - Portamento Up     9 - SampleOffset
; 2 - Portamento Down   A - VolumeSlide
; 3 - TonePortamento    B - PositionJump
; 4 - Vibrato           C - Set Volume
; 5 - ToneP + VolSlide  D - PatternBreak
; 6 - Vibra + VolSlide  E - Misc. Cmds
; 7 - Tremolo           F - Set Speed
;
;
;              E - COMMANDS
;              ------------
; The E command has been altered to
; contain more commands than one.
; E0- Filter On/Off     E8- * NOT USED *
; E1- Fineslide Up      E9- Retrig Note
; E2- Fineslide Down    EA- FineVol Up
; E3- Glissando Control EB- FineVol Down
; E4- Vibrato Control   EC- NoteCut
; E5- Set Finetune      ED- NoteDelay
; E6- Patternloop       EE- PatternDelay
; E7- Tremolo Control   EF- Invert Loop
;
;
;  Cmd 0. Arpeggio [Range:$0-$F/$0-$F]
;  -----------------------------------
; Usage: $0 + 1st halfnote add
;           + 2nd halfnote add
; Arpeggio is used to simulate chords.
; This is done by rapidly changing the
; pitch between 3(or 2) different notes.
; It sounds very noisy and grainy on
; most samples, but ok on monotone ones.
; Example: C-300047  C-major chord:
;          (C+E+G  or C+4+7 halfnotes)
;          C-300037  C-minor chord:
;          (C+D#+G or C+3+7 halfnotes)
;
;
;  Cmd 1. Portamento up [Speed:$00-$FF]
;  ------------------------------------
; Usage: $1 + portamento speed
; Portamento up will simply slide the
; sample pitch up. You can NOT slide
; higher than B-3! (Period 113)
; Example: C-300103  1 is the command,
;            3 is the portamentospeed.
; NOTE: The portamento will be called as
; many times as the speed of the song.
; This means that you'll sometimes have
; trouble sliding accuratly. If you
; change the speed without changing the
; sliderates, it will sound bad...
;
;
;  Cmd 2. Portamento down [Speed:$00-FF]
;  -------------------------------------
; Usage: $2 + portamento speed
; Just like command 1, except that this
; one slides the pitch down instead.
; (Adds to the period).
; You can NOT slide lower than C-1!
; (Period 856)
; Example: C-300203  2 is the command,
;            3 is the portamentospeed.
;
;
; Cmd 3. Tone-portamento [Speed:$00-$FF]
; --------------------------------------
; Usage: Dest-note + $3 + slidespeed
; This command will automatically slide
; from the old note to the new.
; You don't have to worry about which
; direction to slide, you need only set
; the slide speed. To keep on sliding,
; just select the command $3 + 00.
; Example: A-200000  First play a note.
;          C-300305  C-3 is the note to
;               slide to, 3 the command,
;               and 5 the speed.
;
;
; Cmd 4. Vibrato [Rate:$0-$F,Dpth:$0-$F]
; --------------------------------------
; Usage: $4 + vibratorate + vibratodepth
; Example: C-300481  4 is the command,
;       8 is the speed of the vibrato,
;   and 1 is the depth of the vibrato.
; To keep on vibrating, just select
; the command $4 + 00. To change the
; vibrato, you can alter the rate,
; depth or both. Use command E4- to
; change the vibrato-waveform.
;
;
; Cmd 5. ToneP + Volsl [Spd:$0-$F/$0-$F]
; --------------------------------------
; Usage: $5 + upspeed + downspeed
; This command will continue the current
; toneportamento and slide the volume
; at the same time. Stolen from NT2.0.
; Example: C-300503  3 is the speed to
;                turn the volume down.
;          C-300540  4 is the speed to
;                         slide it up.
;
;
; Cmd 6. Vibra + Volsl [Spd:$0-$F/$0-$F]
; --------------------------------------
; Usage: $6 + upspeed + downspeed
; This command will continue the current
; vibrato and slide the volume at the
; same time. Stolen from NT2.0.
; Example: C-300605  5 is the speed to
;                turn the volume down.
;          C-300640  4 is the speed to
;                         slide it up.
;
;
; Cmd 7. Tremolo [Rate:$0-$F,Dpth:$0-$F]
; --------------------------------------
; Usage: $7 + tremolorate + tremolodepth
; Tremolo vibrates the volume.
; Example: C-300794  7 is the command,
;       9 is the speed of the tremolo,
;   and 4 is the depth of the tremolo.
; To keep on tremoling, just select
; the command $7 + 00. To change the
; tremolo, you can alter the rate,
; depth or both. Use command E7- to
; change the tremolo-waveform.
;
;
;
; Cmd 9. Set SampleOffset [Offs:$00-$FF]
; --------------------------------------
; Usage: $9 + Sampleoffset
; This command will play from a chosen
; position in the sample, and not from
; the beginning. The two numbers equal
; the two first numbers in the length
; of the sample. Handy for speech-
; samples.
; Example: C-300923  Play sample from
;                    offset $2300.
;
;
; Cmd A. Volumeslide [Speed:$0-$F/$0-$F]
; --------------------------------------
; Usage: $A + upspeed + downspeed
; Example: C-300A05  5 is the speed to
;                turn the volume down.
;          C-300A40  4 is the speed to
;                         slide it up.
; NOTE: The slide will be called as
; many times as the speed of the song.
; The slower the song, the more the
; volume will be changed on each note.
;
;
;   Cmd B. Position-jump [Pos:$00-$7F]
;   ----------------------------------
; Usage: $B + position to continue at
; Example: C-300B01  B is the command,
;                 1 is the position to
;                 restart the song at.
; This command will also perform a
; pattern-break (see 2 pages below).
; You can use this command instead of
; restart as on noisetracker, but you
; must enter the position in hex!
;
;
;   Cmd C. Set volume [Volume:$00-$40]
;   ----------------------------------
; Usage: $C + new volume
; Well, this old familiar command will
; set the current volume to your own
; selected. The highest volume is $40.
; All volumes are represented in hex.
; (Programmers do it in hex, you know!)
; Example: C-300C10  C is the command,
;       10 is the volume (16 decimal).
;
;
;      Cmd D. Pattern-break
;      [Pattern-pos:00-63, decimal]
;      ----------------------------
; Usage: $D + pattern-position
; This command just jumps to the next
; song-position, and continues play
; from the patternposition you specify.
; Example: C-300D00  Jump to the next
;     song-position and continue play
;            from patternposition 00.
;      Or: C-300D32  Jump to the next
;     song-position and continue play
;    from patternposition 32 instead.
;
;
;    Cmd E0. Set filter [Range:$0-$1]
;    --------------------------------
; Usage: $E0 + filter-status
; This command jerks around with the
; sound-filter on some A500 + A2000.
; All other Amiga-users should keep out
; of playing around with it.
; Example: C-300E01  disconnects filter
;                 (turns power LED off)
;          C-300E00  connects filter
;                  (turns power LED on)
;
;
;   Cmd E1. Fineslide up [Range:$0-$F]
;   ----------------------------------
; Usage: $E1 + value
; This command works just like the
; normal portamento up, except that
; it only slides up once. It does not
; continue sliding during the length of
; the note.
; Example: C-300E11  Slide up 1 at the
;               beginning of the note.
; (Great for creating chorus effects)
;
;
;  Cmd E2. Fineslide down [Range:$0-$F]
;  ------------------------------------
; Usage: $E2 + value
; This command works just like the
; normal portamento down, except that
; it only slides down once. It does not
; continue sliding during the length of
; the note.
; Example: C-300E26  Slide up 6 at the
;               beginning of the note.
;
;
;  Cmd E3. Glissando Ctrl [Range:$0-$1]
;  ------------------------------------
; Usage: $E3 + Glissando-Status
; Glissando must be used with the tone-
; portamento command. When glissando is
; activated, toneportamento will slide
; a halfnote at a time, instead of a
; straight slide.
; Example: C-300E31  Turn Glissando on.
;          C-300E30  Turn Glissando off.
;
;
;      Cmd E4. Set vibrato waveform
;      [Range:$0-$3]
;      ----------------------------
; Usage: $E4 + vibrato-waveform
; Example: C-300E40  Set sine(default)
;               E44  Don't retrig WF
;          C-300E41  Set Ramp Down
;               E45  Don't retrig WF
;          C-300E42  Set Squarewave
;               E46  Don't retrig WF
;          C-300E43  Set Random
;               E47  Don't retrig WF
;
;
;   Cmd E5. Set finetune [Range:$0-$F]
;   ----------------------------------
; Usage: $E5 + finetune-value
; Example: C-300E51  Set finetune to 1.
; Use these tables to figure out the
; finetune-value.
; Finetune: +7 +6 +5 +4 +3 +2 +1  0
;    Value:  7  6  5  4  3  2  1  0
; Finetune: -1 -2 -3 -4 -5 -6 -7 -8
;    Value:  F  E  D  C  B  A  9  8
;
;
;   Cmd E6. PatternLoop [Loops:$0-$F]
;   ----------------------------------
; Usage: $E6 + number of loops
; This command will loop a part of a
; pattern.
; Example: C-300E60  Set loopstart.
;          C-300E63  Jump to loop 3
;           times before playing on.
;
;
;      Cmd E7. Set tremolo waveform
;      [Range:$0-$3]
;      ----------------------------
; Usage: $E7 + tremolo-waveform
; Example: C-300E70  Set sine(default)
;               E74  Don't retrig WF
;          C-300E71  Set Ramp Down
;               E75  Don't retrig WF
;          C-300E72  Set Squarewave
;               E76  Don't retrig WF
;          C-300E73  Set Random
;               E77  Don't retrig WF
;
;
;    Cmd E9. Retrig note [Value:$0-$F]
;    ---------------------------------
; Usage: $E9 + Tick to Retrig note at.
; This command will retrig the same note
; before playing the next. Where to
; retrig depends on the speed of the
; song. If you retrig with 1 in speed 6
; that note will be trigged 6 times in
; one note slot. Retrig on hi-hats!
; Example: C-300F06  Set speed to 6.
;          C-300E93  Retrig at tick 3
;                    out of 6.
;
;
;   Cmd EA. FineVolsl up [Range:$0-$F]
;   ----------------------------------
; Usage: $EA + value
; This command works just like the
; normal volumeslide up, except that
; it only slides up once. It does not
; continue sliding during the length of
; the note.
; Example: C-300EA3  Slide volume up 1
;        at the beginning of the note.
;
;
;  Cmd EB. FineVolsl down [Range:$0-$F]
;  ------------------------------------
; Usage: $EB + value
; This command works just like the
; normal volumeslide down, except that
; it only slides down once. It does not
; continue sliding during the length of
; the note.
; Example: C-300EB6  Slide volume down
;       6 at the beginning of the note.
;
;
;     Cmd EC. Cut note [Value:$0-$F]
;     ------------------------------
; Usage: $EC + Tick to Cut note at.
; This command will cut the note
; at the selected tick, creating
; extremely short notes.
; Example: C-300F06  Set speed to 6.
;          C-300EC3  Cut at tick 3 out
;                    of 6.
; Note that the note is not really cut,
; the volume is just turned down.
;
;
;     Cmd ED. NoteDelay [Value:$0-$F]
;     -------------------------------
; Usage: $ED + ticks to delay note.
; This command will delay the note
; to the selected tick.
; Example: C-300F06  Set speed to 6.
;          C-300ED3  Play note at tick
;                    3 out of 6.
;
;
;   Cmd EE. PatternDelay [Notes:$0-$F]
;   ----------------------------------
; Usage: $EE + notes to delay pattern.
; This command will delay the pattern
; the selected numbers of notes.
; Example: C-300EE8  Delay pattern 8
;           notes before playing on.
; All other effects are still active
; when the pattern is being delayed.
;
;
;    Cmd EF. Invert Loop [Speed:$0-$F]
;    ---------------------------------
; Usage: $EF + Invertspeed
; This command will need a short loop
; ($10,20,40,80 etc. bytes) to work.
; It will invert the loop byte by byte.
; Sounds better than funkrepeat...
; Example: C-300EF8 Set invspeed to 8.
; To turn off the inverting, set
; invspeed to 0, or press ctrl + Z.
;
;
;    Cmd F. Set speed [Speed:$00-$FF]
;    --------------------------------
; Usage: $F + speed
; This command will set the speed of the
; song.


       mov      eax,8      ; 8 bit
       mov      ebx,edi    ; memory adress
       call     save_wav   ; capture sample from screen


       mov      edx,.ptr
       mov      eax,mod_file_name
       mov      ecx,edi
       sub      ecx,edx
       call     save_fileA
       mfree    .ptr
       mov      esp,ebp
       pop      ebp
ret
; files routines
; 3ds, chunks, asc, stl, ply:: save
;======================================================================
;==============================================================================
save_chunks_file:
       push      ebp
       mov       ebp,esp
       .size1    equ [ebp-4]
       .size2    equ [ebp-8]
       .buff     equ [ebp-12]

       mov       ecx,[triangles_count_var]
       add       ecx,ecx
       push      ecx                     ; siz1
       mov       eax,[chunks_count]
       shl       eax,4
       add       eax,ecx
       push      eax                     ; siz2
       add       eax,70
       malloc    eax
       push      eax                     ; buff
       mov       esi,[chunks_ptr]
       mov       edi,eax
       mov       ecx,.size1
       shr       ecx,2
       inc       ecx
       cld
       rep       movsd
       mov       edi,.buff
       add       edi,.size1
       mov       esi,[chunks_desc_ptr]
       mov       ecx,[chunks_count]
       shl       ecx,2
       rep       movsd
       mov       edx,.buff   ;[chunks_ptr]
       or        edx,edx
       jz        .ff
       mov       eax,Chfile_name
       mov       ecx,.size2  ;[triangles_count_var]
       call      save_fileA
     .ff:
       mfree     .buff
       mov       esp,ebp
       pop       ebp
ret
;===================================================================================
;===================================================================================
save3ds:
       pushad
       mov      ebp,esp
       sub      esp,20

       .3dbuffer_ptr  equ [ebp-4]
       .file_handle   equ [ebp-8]
       .bytes_written equ [ebp-12]
       .file_size     equ [ebp-16]
       .acc           equ dword[ebp-20]
       
       mov       eax,[points_count_var]
       add       eax,[triangles_count_var] ; to big mem, I know
       add       eax,100
       imul      eax,12
       malloc    eax
       mov       .3dbuffer_ptr,eax
       mov       edx,[triangles_count_var]
       mov       ecx,[points_count_var]
       ; cmp     edx,ecx
       ; cmovb   edx,ecx
       cmp       edx,65535     ; above 65535 elements  ???
       ja        .chu          ; so - old routines
       cmp       ecx,65535
       ja        .chu
       mov       edi,eax
       mov       [edi],word 4d4dh
       add       edi,6
       mov       [edi],word 3d3dh
       add       edi,6
       mov       [edi],word 4000h
       add       edi,6
       mov       [edi],byte 0
       inc       edi
       mov       [edi],word 4100h     ;    [global_points_counter]
       add       edi,6
       mov       [edi],word 4110h
       ; mov     ecx,[points_count_var]
       mov       edx,ecx
       mov       [edi+6],cx
       add       edi,8
       mov       esi,[points_rotated_ptr];   [points_r_ptr]   ;
       xor       ebx,ebx
       lea       ecx,[ecx*3]
       cld
       rep       movsd
       mov       [edi],word 4120h
       mov       ecx,[triangles_count_var]
       mov       [edi+6],cx
       add      edi,8
       mov       esi,[triangles_ptr]
       cld
     @@:
       movups    xmm0,[esi]
       packssdw  xmm0,xmm0
       movlps    [edi],xmm0
       mov       dword[edi+6],0
       add       esi,12
       add       edi,8
       loop      @b
       jmp       .wrt
     .chu:
       mov       ebx,[chunks_desc_ptr]
       cld
       mov       edi,eax
       mov       [edi],word 4d4dh
       add       edi,6
       mov       [edi],word 3d3dh
       add       edi,6
       xor       eax,eax
       mov       .acc,eax   ; tri acc
       ; add     ebx,16
       xor       ecx,ecx
     .4k:
       push      ecx
       mov       [edi],word 4000h
       add       edi,6
       mov       [edi],byte 0
       inc       edi
       mov       [edi],word 4100h     ;    [global_points_counter]
       add       edi,6
       mov       [edi],word 4110h
       ; mov     ecx,[points_count_var]
       ; mov     edx,ecx

       ; mov     [edi+6],cx
       mov       ecx,[ebx+4]
       mov       [edi+6],cx      ; vert cnt
       add       edi,8
       mov       esi,[ebx+8]
       ; inc     esi
       imul      esi,12
       add       esi,[points_rotated_ptr]
       ; add     esi,[ebx+8] ; vert ofs
       ; xor     ebx,ebx
       lea       ecx,[ecx*3]
     @@:
       rep       movsd
       mov       [edi],word 4120h
       mov       ecx,[ebx]
       ; inc     ecx
       pop       edx
       add       ecx,edx
       mov       [edi+6],cx
       add       edi,8
       mov       esi,[ebx+12]
       inc       esi
       imul      esi,12
       add       esi,[triangles_ptr]
       ; add     esi,[ebx+12]          ; tri ofset
       cld
       movss     xmm2,.acc
       shufps    xmm2,xmm2,0
     @@:
       movups    xmm0,[esi]
       psubd     xmm0,xmm2
       packusdw  xmm0,xmm0
       movlps    [edi],xmm0
       mov       word[edi+6],0
       add       esi,12
       add       edi,8
       loop      @b
       mov       ecx,[ebx+4]  ; vert cnt
       add       .acc,ecx
       add       ebx,16
       mov       ecx,edx
       inc       ecx
       ; cmp     ecx,[chunks_count]
       ; jne     .4k
       cmp       dword[ebx],0
       jne       .4k
     .wrt:
       mov       ebx,.3dbuffer_ptr
       sub       edi,.3dbuffer_ptr
       mov       [ebx+2],edi
       mov       .file_size,edi
       mov       ecx,edi
       lea       edx,[ebx]
       mov       eax,Bfile_name
       call      save_fileA
       mfree     .3dbuffer_ptr
       mov       esp,ebp
       popad
ret
;================================================================
write_stl:
       .file_buff  equ  dword[ebp-4]
       push        ebp
       mov         ebp,esp
       mov         ebx,[triangles_count_var]   ;
       imul        ebx,50
       add         ebx,2000
       malloc      ebx
       push        eax
       ; mov         .file_buff,eax
       mov         edi,eax
       mov         eax,3
       cvtsi2ss    xmm2,eax
       shufps      xmm2,xmm2,0
       cld
       mov         eax,'mac '
       stosd
       add         edi,76
       mov         ecx,[triangles_count_var]
       mov         eax,ecx
       stosd
       mov         ebx,[triangles_normals_ptr]
       mov         esi,[triangles_ptr]
     .lab_off:
       push        ecx
       xchg        esi,ebx
       movsd
       movsd
       movsd
       xchg        esi,ebx
       mov         ecx,3
     .bbb:
       lodsd
       imul        eax,12
       add         eax,[points_r_ptr]
       movups      xmm0,[eax]
       addps       xmm0,xmm2
       movups      [edi],xmm0
       add         edi,12
       loop        .bbb
       add         edi,2
       pop         ecx
       loop        .lab_off
       ; write file
       sub         edi,.file_buff
       mov         ecx,edi
       mov         eax,stl_file_name
       mov         edx,.file_buff
       call        save_fileA
       mfree       .file_buff
       mov         esp,ebp
       pop         ebp
ret
;================================================================
write_ply:
       .pppl       equ  dword[ebp-4]
       .file_buff  equ  dword[ebp-8]
       .tcv        equ  dword[ebp-12]
       .pccv       equ  dword[ebp-16]

       push    ebp
       mov     ebp,esp
       sub     esp,20
       mov     ebx,[triangles_count_var]
       mov     edx,[points_count_var]
       mov     .tcv,ebx
       mov     .pccv,edx
       imul    ebx,13
       add     ebx,600
       imul    edx,12
       add     ebx,edx
       malloc  ebx
       mov     .file_buff,eax
       cld
       mov     esi,ply_header
       mov     edi,.file_buff
     @@:
       lodsb
       cmp     al,'#'
       je      @f
       stosb
       jmp     @b
     @@:
       mov     eax,.pccv ;[points_count_var]
       push    esi
       mov     esi,edi
       call    itoa
       ; mov    esi,edi
       dec     edi
       pop     esi
       cld
     @@:
       lodsb
       cmp     al,'#'
       je      @f
       stosb
       jmp     @b
     @@:
       mov     eax,.tcv  ;[triangles_count_var]
       push    esi
       mov     esi,edi
       call    itoa
       dec     edi
       ; mov   esi,edi
       pop     esi
       cld
     @@:
       lodsb
       cmp     al,'#'
       je      @f
       stosb
       jmp     @b
     @@:
       mov     esi,[points_r_ptr]
       mov     ecx,.pccv ;[points_count_var]
       lea     ecx,[ecx*3]
       cld
       rep     movsd
       mov     esi,[triangles_ptr]
       mov     ecx,.tcv  ;[triangles_count_var]
       mov     al,3
       @@:
       stosb
       movsd
       movsd
       movsd
       loop    @b
       mov     edx,.file_buff
       sub     edi,edx
       mov     eax,ply_file_name
       mov     ecx,edi
       call    save_fileA
       mfree   .file_buff
       mov     esp,ebp
       pop     ebp
ret
;=================================================================================
write_asc:
       .counter    equ  dword[ebp-4]
       .file_buff  equ  dword[ebp-8]
       .pccv       equ  dword[ebp-12]
       .tccv       equ  dword[ebp-16]

       push    ebp
       mov     ebp,esp
       sub     esp,64
       mov     eax,[points_count_var]      ;   -
       mov     .pccv,eax
       shl     eax,6                       ;   Calc
       mov     ebx,[triangles_count_var]   ;   aproximate
       mov     .tccv,ebx
       shl     ebx,5                       ;   size of
       lea     ebx,[ebx*3]                 ;   asc file
       add     eax,ebx                     ;   buffer.
       add     eax,65536
       malloc  eax  ;   -
       mov     .file_buff,eax
       fninit
       mov     edi,eax  ;.file_buff;asc_file_buffer
       mov     esi,asc_main_header
       cld
     @@:
       lodsb
       cmp     al,1
       jz      @f
       stosb
       jmp     @b
     @@:
       mov     esi,asc_info_header
     @@:
       lodsb
       cmp     al,1
       jz      @f
       stosb
       jmp     @b
     @@:
       push    esi  ; -> position in header info
       mov     eax,.pccv  ;[points_count_var]
       mov     esi,edi
       call    itoa              ; unsigned dword integer to ascii procedure
       pop     esi
       inc     esi
     @@:
       lodsb
       cmp     al,1
       jz      @f
       stosb
       jmp     @b
     @@:
       push    esi
       mov     eax,.tccv   ;[triangles_count_var]
       mov     esi,edi
       call    itoa
       pop     esi
       inc     esi
     @@:
       lodsb
       cmp     al,1
       jz      @f
       stosb
       jmp     @b
     @@:
       ;=============================================================
       ;================vertex list parser===========================
       ;=============================================================
       xor    ecx,ecx
     .again_vertex:
       push   ecx
       mov    esi,asc_one_vertex_formula
     @@:
       lodsb
       cmp    al,1
       jz     @f
       stosb
       jmp    @b
     @@:
       mov    eax,ecx
       push   esi
       mov    esi,edi
       call   itoa
       pop    esi
       inc    esi
       xor    ebx,ebx
       .next_vertex_coef:
       push   ebx
     @@:
       lodsb
       cmp    al,1
       jz     @f
       stosb
       jmp    @b
     @@:
       push   esi ecx
       lea    esi,[ecx*3]
       shl    esi,2
       add    esi,[points_r_ptr]
       add    esi,ebx
       mov    ecx,7
       call   ftoa
       pop    ecx esi
       pop    ebx
       add    ebx,4
       cmp    ebx,12
       jnz    .next_vertex_coef
     @@:
       lodsb
       cmp    al,1
       jz     @f
       stosb
       jmp    @b
     @@:
       pop    ecx
       inc    ecx
       cmp    ecx,.pccv
       jnz    .again_vertex
       mov    esi,asc_face_list_header
     @@:
       lodsb
       cmp    al,1      ; all face header
       jz     @f
       stosb
       jmp    @b
     @@:
       ;=====================================
       ; ==============face list parser======
       ;=====================================
       xor    ecx,ecx
     .again_face:
       push   ecx
       mov    .counter,ecx
       mov    esi,asc_one_face_formula
     @@:
       lodsb
       cmp    al,1
       jz     @f
       stosb
       jmp    @b
     @@:
       mov    eax,ecx
       push   esi
       mov    esi,edi
       call   itoa
       pop    esi
       inc    esi
     @@:
       lodsb
       cmp    al,1
       jz     @f
       stosb
       jmp    @b
     @@:
       xor    ebx,ebx
     .next_face_index:
       push   ebx
       mov    ecx,.counter
       lea    ecx,[ecx*3]
       shl    ecx,2
       mov    eax,[triangles_ptr]
       add    eax,ecx
       mov    eax,dword[eax+ebx]
       push   esi
       mov    esi,edi
       call   itoa
       pop    esi
     @@:
       lodsb
       cmp    al,1
       jz     @f
       stosb
       jmp    @b
     @@:
       pop    ebx
       add    ebx,4
       cmp    ebx,12
       jnz    .next_face_index
       pop    ecx
       inc    ecx
       cmp    ecx,.tccv
       jnz    .again_face
       ; write file
       sub    edi,.file_buff
       mov    ecx,edi
       mov    eax,asc_file_name
       mov    edx,.file_buff
       call   save_fileA
       mfree  .file_buff
       mov    esp,ebp
       pop    ebp
ret
